package com.lightsh.paint;

import java.util.ArrayList;
import java.util.Arrays;

import com.lightsh.common.PaintItem;
import com.lightsh.common.PaintStroke;
import com.lightsh.handwritten.FingerPaintActivity;
import com.lightsh.utility.Constants;
import com.lightsh.utility.Utility;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Bitmap.Config;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class FingerPaintView extends View{
	private static final String TAG = "FingerPaintView";
	private static final boolean DEBUG = Constants.DEBUG;
	
	private Bitmap mBitmap;
	private Canvas mCanvas;
	private Path mPath;
	private Paint mPaint;
	private Paint mBitmapPaint;
	
	private int mBackgroundColor;
	
	private int mWidth;
	private int mHeight;
	
	private float mLastX;
	private float mLastY;
	
	private ArrayList<Float> mTempStroke;
	private ArrayList<PaintStroke> mStrokes;
	private int mType = PaintItem.PAINT_TYPE_NORMAL;
	private long mLastlyTime;
	private long mCreateTime;
	private String mText;
	
	private static final float TOUCH_TOLERANCE = 4;
	private boolean mbChange = false;
	
	public FingerPaintView(Context context, int width, int height){
		super(context);
		init(width, height, null);
	}
	public FingerPaintView(Context context, PaintItem item){
		super(context);
		init(item.getWidth(), item.getHeight(), item);
	}
	
	public ArrayList<PaintStroke> getPaintStrokes(){
		return mStrokes;
	}
	public int getPaintWidth(){
		return mWidth;
	}
	public int getPaintHeight(){
		return mHeight;
	}
	public boolean isChange(){
		return mbChange;
	}
	public String getText(){
		return mText;
	}
	/**
	 * 清除一个比画
	 */
	public void popStroke(){
		if(mStrokes.size() > 0){
			mbChange = true;
			mStrokes.remove(mStrokes.size() - 1);
			redrawStrokes();
		}
	}
	public int getStrokeSize(){
		return mStrokes.size();
	}
	private void init(int width, int height, PaintItem item){
		mWidth = width;
		mHeight = height;
		mBitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
		mCanvas = new Canvas(mBitmap);
		mPath = new Path();
		
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		
		mPaint = new Paint();
		Utility.initDrawPaint(mPaint);
		mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(8);
        
        mBackgroundColor = Color.BLACK;
        
        mTempStroke = new ArrayList<Float>();
        if(item != null){
        	getInfo(item);
        }else{
        	mStrokes = new ArrayList<PaintStroke>();
        	mCreateTime = System.currentTimeMillis();
        	mLastlyTime = System.currentTimeMillis();
        }
	}
	private void getInfo(PaintItem item){
		mStrokes = item.getStrokeList(getContext());
		mType = item.getType();
		mText = item.getText();
		mCreateTime = item.getCreateTime();
		mLastlyTime = item.getLastlyTime();
		
		// 绘制笔画
		redrawStrokes();
	}
	private static void drawStroke(Path path, Paint paint, Canvas canvas, PaintStroke stroke){
		Utility.drawStroke(path, paint, canvas, stroke);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		final float x = event.getX();
		final float y = event.getY();
		switch(event.getAction() & MotionEvent.ACTION_MASK){
		case MotionEvent.ACTION_DOWN:
			onDown(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			onMove(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			onUp(x, y);
			invalidate();
			break;
		}
		return true;
	}
	private void onUp(float x, float y){
		mPath.lineTo(mLastX, mLastY);
		mCanvas.drawPath(mPath, mPaint);
		mPath.reset();
		mTempStroke.add(x);
		mTempStroke.add(y);		
		
//		if(mTempStroke.size() <= 2){
//			// FIXME 是否过滤纯点?
//		}
		PaintStroke ps = addStroke();
		drawStroke(mPath, mPaint, mCanvas, ps);
		
		mTempStroke.clear();
	}
	private void onDown(float x, float y){
		mPath.reset();
		mPath.moveTo(x, y);
		mLastX = x;
		mLastY = y;
		mTempStroke.clear();
		mTempStroke.add(x);
		mTempStroke.add(y);
	}
	private void onMove(float x, float y){
		float dx = Math.abs(x - mLastX);
		float dy = Math.abs(y - mLastY);
		if(dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE){
			Utility.pathQuadTo(mPath, mLastX, mLastY, x, y);
//			mPath.quadTo(mLastX, mLastY, (x + mLastX)/2, (y + mLastY)/2);
			mLastX = x;
			mLastY = y;
			mTempStroke.add(x);
			mTempStroke.add(y);
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
		canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
		canvas.drawPath(mPath, mPaint);
	}
	
	private PaintStroke addStroke(){
		mbChange = true;
		PaintStroke ps = PaintStroke.newInstance(mTempStroke, mPaint.getColor(), 0, (int)mPaint.getStrokeWidth());
		mStrokes.add(ps);
		return ps;
	}
	
	/**
	 * 清除临时Bitmap并且重新绘制
	 */
	private void redrawStrokes(){
		mCanvas.drawColor(mBackgroundColor);		
		for(PaintStroke stroke : mStrokes){
			if(stroke.getWidth() < 8){
				Log.e(TAG, "width = " + stroke.getWidth());
			}
			drawStroke(mPath, mPaint, mCanvas, stroke);
		}
		this.invalidate();
	}
}
